package br.com.mensures.entitymanager;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaQuery;

public class JPAGenericDAO<T> {
	private final Class<T> classe;

	public JPAGenericDAO(Class<T> classe) {
		this.classe = classe;
	}

	public void adiciona(T t) throws Exception {
		//consegue a entity manager
		EntityManager em = JPAUtil.getEntityManager();
		
		
		try {
			
			//abre transacao
			em.getTransaction().begin();
			//persiste o objeto
			em.persist(t);
			//commita a transacao
			em.getTransaction().commit();
			
		} catch (Exception e) {
			// TODO: handle exception
			try {				
				em.getTransaction().rollback();				
			} catch (Exception e2) {
				e.printStackTrace();	
				throw e2;
			}
			
			throw e;
			
		}finally{			
			//fecha a entity manager
			em.close();
			
		}
		
		

		
	}

	public void remove(T t) {
		EntityManager em = JPAUtil.getEntityManager();
		em.getTransaction().begin();

		em.remove(em.merge(t));

		em.getTransaction().commit();
		em.close();
	}

	public void atualiza(T t) {
		EntityManager em = JPAUtil.getEntityManager();
		em.getTransaction().begin();

		em.merge(t);

		em.getTransaction().commit();
		em.close();
	}

	public List<T> listaTodos() {
		EntityManager em = JPAUtil.getEntityManager();
		CriteriaQuery<T> query = em.getCriteriaBuilder().createQuery(classe);
		query.select(query.from(classe));

		List<T> lista = em.createQuery(query).getResultList();

		em.close();
		return lista;
	}
	
	public T buscaPorId(Long id) {
		EntityManager em = JPAUtil.getEntityManager();
		T instancia = em.find(classe, id);
		em.close();
		return instancia;
	}
	
	public int contaTodos() {
		EntityManager em = JPAUtil.getEntityManager();
		long result = (Long) em.createQuery("select count(n) from " + classe.getName() + " n").getSingleResult();
		em.close();
		
		return (int) result;
	}

	public List<T> listaTodosPaginada(int firstResult, int maxResults) {
		EntityManager em = JPAUtil.getEntityManager();
		CriteriaQuery<T> query = em.getCriteriaBuilder().createQuery(classe);
		query.select(query.from(classe));

		List<T> lista = em.createQuery(query).setFirstResult(firstResult)
				.setMaxResults(maxResults).getResultList();

		em.close();
		return lista;
	}


}
